using DslModeling = global::Microsoft.VisualStudio.Modeling;
using DslDesign = global::Microsoft.VisualStudio.Modeling.Design;
using DslDiagrams = global::Microsoft.VisualStudio.Modeling.Diagrams;
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel.Design;
using System.Security.Permissions;
using Microsoft.VisualStudio.Modeling.Design;
using Microsoft.VisualStudio.Modeling;

namespace Guava.ChannelTransformations
{
    public partial class Channel
    {
        public Channel(DslModeling::Store store, params DslModeling::PropertyAssignment[] propertyAssignments)
            : this(store != null ? store.DefaultPartition : null, propertyAssignments)
        {
        }

        /// <summary>
        /// Constructor - custom to add start and end points
        /// </summary>
        /// <param name="partition">Partition where new element is to be created.</param>
        /// <param name="propertyAssignments">List of domain property id/value pairs to set once the element is created.</param>
        public Channel(DslModeling::Partition partition, params DslModeling::PropertyAssignment[] propertyAssignments)
            : base(partition, propertyAssignments)
        {
           if (propertyAssignments == null) {//first time channel is created
              
               StartPoint op1 = null;
               EndPoint op2 = null;
               using (Microsoft.VisualStudio.Modeling.Transaction t = this.Store.TransactionManager.BeginTransaction())
               {
                   this.Store.LoadDomainModels(typeof(ChannelTransformationsDomainModel));
                   op1 = new StartPoint(this.Store);
                   op1.Name = "Start";
                   this.Operator.Add(op1);
                   

                   this.Store.LoadDomainModels(typeof(ChannelTransformationsDomainModel));
                   op2 = new EndPoint(this.Store);
                   op2.Name = "End";
                   this.Operator.Add(op2);
                   t.Commit();

                   op1.FlowTo.Add(op2);
                   op2.FlowFrom = op1;
                   
               }
               
            }
        }
        
        protected override void MergeRelate(DslModeling::ModelElement sourceElement, DslModeling::ElementGroup elementGroup)
        {
            // In general, sourceElement is allowed to be null, meaning that the elementGroup must be parsed for special cases.
            // However this is not supported in generated code.  Use double-deriving on this class and then override MergeRelate completely if you 
            // need to support this case.
            if (sourceElement == null) throw new global::System.ArgumentNullException("sourceElement");

            global::Guava.ChannelTransformations.Operators sourceOperators1 = sourceElement as global::Guava.ChannelTransformations.Operators;
            
            bool startExists = false;
            bool endExists = false;
            int i =0;
            if (sourceOperators1 != null)
            {
                // Create link for path ChannelHasOperator.Operator
                for (i = 0; i < Operator.Count; i++)
                {
                //allow only one start and one end
                    if ((Operator[i].GetType().Name == "StartPoint") && (sourceOperators1.GetType().Name == "StartPoint"))
                        return;

                    if ((Operator[i].GetType().Name == "EndPoint") && (sourceOperators1.GetType().Name == "EndPoint"))
                        return;

                    //make sure one start and end exist before adding other operators
                    if (Operator[i].GetType().Name == "StartPoint") startExists = true;
                    if (Operator[i].GetType().Name == "EndPoint") endExists = true;
                }
                if (endExists && startExists)
                    this.Operator.Add(sourceOperators1);
                else {
                    if ((sourceOperators1.GetType().Name == "EndPoint") || (sourceOperators1.GetType().Name == "StartPoint"))
                        this.Operator.Add(sourceOperators1);
                    else
                    {
                        System.Windows.Forms.MessageBox.Show("Please add Start and End points before adding operators");
                        return;
                    }
                 }
                 Operators op = null;
                 int startIndex= 0;
                 //operator is added to interface: establish link
                 if (Operator.Count == 1) return;
                 for (int j = 0; j < Operator.Count; j++)
                 {
                     if (Operator[j].GetType().Name == "StartPoint")
                     {
                         startIndex = j;
                         break;
                     }
                 }
                 if (Operator[startIndex].FlowTo.Count == 0)        
                 {
                     for (int j = 0; j < Operator.Count; j++)
                     {
                         if (Operator[j].GetType().Name == "EndPoint")
                         {
                             op = Operator[j];
                             Operator[startIndex].FlowTo.Add(op);
                             break;
                         }
                     }
                 }
                 else
                 {
                     Operators current;
                     //find the last operator that has flowto empty and make it sourceoperator1
                     for (int j = 0; j < Operator.Count; j++)
                     {
                         current = Operator[j];
                         if (current.FlowTo.Count == 0)
                         {
                             current.FlowTo.Clear();
                             current.FlowTo.Add(sourceOperators1);
                             break;
                             //sourceOperators1.FlowFrom = current;
                         }
                         else
                             continue;

                     }
                 }
                 
                 return;
            }
            // Fall through to base class if this class hasn't handled the merge.
            base.MergeRelate(sourceElement, elementGroup);
        }

        private void ConnectOperators(global::Guava.ChannelTransformations.Operators sourceOperators1, global::Guava.ChannelTransformations.Operators targetOperator1)
        {
            Operators op = sourceOperators1.FlowTo[0];
            sourceOperators1.FlowTo.ReplaceAt(0, targetOperator1);
            targetOperator1.FlowTo.Add(op);
        }
        protected override bool CanMerge(DslModeling::ProtoElementBase rootElement, DslModeling::ElementGroupPrototype elementGroupPrototype)
        {
            if (elementGroupPrototype == null) throw new global::System.ArgumentNullException("elementGroupPrototype");

            if (rootElement != null)
            {
                DslModeling::DomainClassInfo rootElementDomainInfo = this.Partition.DomainDataDirectory.GetDomainClass(rootElement.DomainClassId);

                
                    return false;

            }
            return base.CanMerge(rootElement, elementGroupPrototype);
        }

       
    }

    public partial class VSplit
    {
        ListType property1Storage;
        ListType ColumnsToSplitStorage;


        public ListType GetTableNamesListValue()
        {

            if (property1Storage == null)
                property1Storage = new ListType();

            return property1Storage;


        }
        public void SetTableNamesListValue(object newvalue)
        {
            property1Storage = (ListType)newvalue;
        }
        public ListType GetcolumnsToSplitValue()
        {
            if (ColumnsToSplitStorage == null)
                ColumnsToSplitStorage = new ListType();

            return ColumnsToSplitStorage;

        }
        internal void SetcolumnsToSplitValue(object newValue)
        {
            ColumnsToSplitStorage = (ListType)newValue;
        }

        
    }


   


    public partial class HMerge
    {
       
        ListType property1Storage;

        public ListType GettablesToMergeValue()
        {

            if (property1Storage == null)
                property1Storage = new ListType();

            return property1Storage;


        }
        public void SettablesToMergeValue(object newvalue)
        {
            property1Storage = (ListType)newvalue;
        }
        
        
    }


    public partial class Audit
    {
        ListType property1Storage;

        public ListType GetTablesToAuditValue()
        {

            if (property1Storage == null)
                property1Storage = new ListType();

            return property1Storage;


        }
        public void SetTablesToAuditValue(object newvalue)
        {
            property1Storage = (ListType)newvalue;
        }

    }

    public partial class Apply
    {
        ListType property1Storage;

        public ListType GetinNamesValue()
        {

            if (property1Storage == null)
                property1Storage = new ListType();

            return property1Storage;


        }
        public void SetinNamesValue(object newvalue)
        {
            property1Storage = (ListType)newvalue;
        }

        ListType outTablesStorage;

        public ListType GetoutNamesValue()
        {

            if (outTablesStorage == null)
                outTablesStorage = new ListType();

            return outTablesStorage;


        }
        public void SetoutNamesValue(object newvalue)
        {
            outTablesStorage = (ListType)newvalue;
        }
    }

    public partial class Adorn
    {
        ListType property1Storage;

        public ListType GettablesToAdornValue()
        {

            if (property1Storage == null)
                property1Storage = new ListType();

            return property1Storage;


        }
        public void SettablesToAdornValue(object newvalue)
        {
            property1Storage = (ListType)newvalue;
        }

    }

    public partial class Unpivot
    {
        ListType property1Storage;

        public ListType GetUnpivotTablesValue()
        {

            if (property1Storage == null)
                property1Storage = new ListType();

            return property1Storage;


        }
        public void SetUnpivotTablesValue(object newvalue)
        {
            property1Storage = (ListType)newvalue;
        }

    }

    public partial class Pivot
    {
        ListType property1Storage;
        ListType property1Storage1;
        ListType property1Storage2;

        public ListType GettablesValue()
        {

            if (property1Storage == null)
                property1Storage = new ListType();

            return property1Storage;


        }
        public void SettablesValue(object newvalue)
        {
            property1Storage = (ListType)newvalue;
        }


        public ListType GetattrColumnsValue()
        {

            if (property1Storage1 == null)
                property1Storage1 = new ListType();

            return property1Storage1;


        }
        public void SetattrColumnsValue(object newvalue)
        {
            property1Storage1 = (ListType)newvalue;
        }

        public ListType GetvalColumnsValue()
        {

            if (property1Storage2 == null)
                property1Storage2 = new ListType();

            return property1Storage2;


        }
        public void SetvalColumnsValue(object newvalue)
        {
            property1Storage2 = (ListType)newvalue;
        }
    }

    public partial class VMerge
    {
        ListType property1Storage;


        public ListType GetPropConfigsValue()
        {

            if (property1Storage == null)
                property1Storage = new ListType();

            return property1Storage;


        }
        public void SetPropConfigsValue(object newvalue)
        {
            property1Storage = (ListType)newvalue;
        }
       
    }

    public partial class TableToDisplay
    {
        ListType property1Storage;


        public ListType GetColumnsValue()
        {

            if (property1Storage == null)
                property1Storage = new ListType();

            return property1Storage;


        }
        public void SetColumnsValue(object newvalue)
        {
            property1Storage = (ListType)newvalue;
        }

    }


    public partial class RenameColumn
    {
        MyDictionary property1Storage;


        public MyDictionary GetTableCurrentColmunNewColumnValue()
        {

            if (property1Storage == null)
                property1Storage = new MyDictionary();

            return property1Storage;


        }
        public void SetTableCurrentColmunNewColumnValue(object newvalue)
        {
            property1Storage = (MyDictionary)newvalue;
        }
       

    }
    public partial class RenameTable
    {
       
        MyDictionary property1Storage;


        public MyDictionary GetCurrentTableNewTableValue()
        {

            if (property1Storage == null)
                property1Storage = new MyDictionary();

            return property1Storage;


        }
        public void SetCurrentTableNewTableValue(object newvalue)
        {
            property1Storage = (MyDictionary)newvalue;
        }
       


    }


    [Serializable()]
    public class MyStrings
    {
        private string val;


        public MyStrings()
        {
            this.val = "String";
        }
        public MyStrings(string v)
        {
            this.val = v;
        }

        public String Name
        {
            get
            {
                return val;
            }
            set
            {
                val = value;

            }
        }



    }
    [Serializable()]
    public class ListType : System.Collections.Generic.List<MyStrings>
    {

    }
    [Serializable()]
    public class MyDictionary : System.Collections.Generic.List<MyStrings>
    {

    }
}